﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

using com.dz.ct.components;
using com.dz.ct.db;
using com.dz.ct.common;
using System.Threading;
using System.Text.RegularExpressions;
using com.dz.ct.components.SmallSite.www.google.com;
using System.Web;
using com.dz.ct.html;

namespace com.dz.ct.business
{
    public class ZCNCollectManager
    {
        //文件读写
        FileManager m_file_mgr = new FileManager();
        /// <summary>
        /// 线程数量
        /// </summary>
        public int ThreadCount { get; set; }

        /// <summary>
        /// 索引
        /// </summary>
        private int m_reg_index = 0;

        /// <summary>
        /// 需要收录章节的书籍
        /// </summary>
        private DataSet m_ds = null;

        /// <summary>
        /// 需要收录章节的书籍记录
        /// </summary>
        private int m_total_count = 0;

        /// <summary>
        /// 数据访问对象
        /// </summary>
        private DBManager m_db_mgr = new DBManager();

        /// <summary>
        /// 需要收录书籍的SQL
        /// </summary>
        public string BookSQL { get; set; }

        /// <summary>
        /// 触发发送消息的事件
        /// </summary>
        public event SendMsgEventHandler SendMsg;

        /// <summary>
        /// 接口变量
        /// </summary>
        public string ComName { get; set; }

          /// <summary>
        /// 书籍列表地址
        /// </summary>
        public string BookUrl { get; set; }


        /// <summary>
        /// 站点配置
        /// </summary>
        public DataRow SiteConfig { get; set; }

        /// <summary>
        /// 每个线程的收录量
        /// </summary>
        private int m_per_thread_count = 0;

        /// <summary>
        /// 开始页码
        /// </summary>
        public int StartPageIndex { get; set; }

        /// <summary>
        /// 结束页码
        /// </summary>
        public int EndPageIndex { get; set; }

        private IBigSiteObject m_obj = null;

        #region 消息回送
        /// <summary>
        /// 发送消息到客户端
        /// </summary>
        /// <param name="i_msg"></param>
        private void SendMsg2Client(string i_msg, MsgType i_msg_type)
        {
            SendMsgEventArgs e = new SendMsgEventArgs();
            e.Msg = i_msg;
            e.MsgType = i_msg_type;
            if (SendMsg != null)
            {
                SendMsg(this, e);
            }

        }
        #endregion

        /// <summary>
        /// 开始收集小说章节
        /// </summary>
        public void StartCollectChapter()
        {
            try
            {
                if (string.IsNullOrEmpty(BookSQL))
                {
                    BookSQL = "select a.bookId,b.bookName,a.chapterUrl searchUrl,b.lastUpdateChapterName,b.bookCategoryId,b.chapterUrl,c.* from tbbooksearch a,tbbook b,tbBookSmallSite c where a.bookid=b.bookid and a.siteId=c.siteId and c.siteId=1 and not exists(select 1 from tbbookcompleted e where b.bookId=e.bookId)";
                }

                m_obj = ComManager.CreateBigSiteObj(ComName);

                m_ds = m_db_mgr.QueryData(BookSQL);

                if (m_ds != null && m_ds.Tables[0].Rows.Count > 0)
                {
                    m_total_count = m_ds.Tables[0].Rows.Count;

                    m_per_thread_count = m_total_count / ThreadCount;

                    for (int index = 0; index < ThreadCount; index++)
                    {
                        Thread t_thd = new Thread(ThreadCollect);

                        t_thd.Start(index);
                    }

                    for (int index = ThreadCount * m_per_thread_count; index < m_total_count; index++)
                    {
                        CollectSingleBook(m_ds.Tables[0].Rows[index]);
                    }

                    SendMsg2Client(string.Format("{0}本小说需要收录章节，{1}个线程同时进行，每个线程{2}本书", m_total_count, ThreadCount, m_per_thread_count), MsgType.Total);
                }



            }
            catch (Exception ex)
            {
                if (ex.ToString().IndexOf("线程") > -1)
                {
                    SendMsg2Client("已经停止!", MsgType.Total);
                }
                else
                {
                    LogHelper.Error("收集小说章节失败" + ex.ToString());
                }
            }
        }


        /// <summary>
        /// 收集小说章节
        /// </summary>
        /// <param name="i_thd_index"></param>
        private void ThreadCollect(object i_thd_index)
        {
            int t_thd_index = (int)i_thd_index;

            for (int index = t_thd_index * m_per_thread_count; index < (t_thd_index + 1) * m_per_thread_count; index++)
            {
                CollectSingleBook(m_ds.Tables[0].Rows[index]);
            }

        }

        /// <summary>
        /// 收集一本小说
        /// </summary>
        /// <param name="i_book_row"></param>
        private void CollectSingleBook(DataRow i_book_row)
        {
            try
            {
                List<BookChapterInfo> t_chapter_list_source = m_obj.CollectChapterList(i_book_row["chapterUrl"].ToString());


                string t_last_update_chapter_name = i_book_row["lastUpdateChapterName"] == null ? "" : i_book_row["lastUpdateChapterName"].ToString();

                int t_chapter_index = 0;

                int t_vip_chapter_count = 0;
                int t_chapter_count = 0;

                string t_chapter_content = string.Empty;

                bool t_is_compared = false;

                if (t_chapter_list_source != null && t_chapter_list_source.Count > 0)
                {
                    SendMsg2Client(string.Format("小说：{2} 从地址：{0} 收集到{1}个章节..", i_book_row["chapterUrl"].ToString(), t_chapter_list_source.Count, i_book_row["bookName"]), MsgType.Total);

                    if (!string.IsNullOrEmpty(t_last_update_chapter_name))
                    {
                        t_chapter_index = t_chapter_list_source.FindIndex(delegate(BookChapterInfo t_chapter_info)
                        {
                            t_is_compared =NetSiteCatchManager.CompareChapterName(t_chapter_info.ChapterName, t_last_update_chapter_name);
                            if (t_is_compared == false)
                            {
                                t_is_compared =NetSiteCatchManager.CompareChapterName(t_last_update_chapter_name, t_chapter_info.ChapterName);
                            }
                            return t_is_compared;
                        });
                    }
                }
                if (t_chapter_index < 0)
                    t_chapter_index = 0;

                long t_book_id = 0;
                long t_chapter_id = 0;


                if (!long.TryParse(i_book_row["bookId"].ToString(), out t_book_id))
                    t_book_id = 0;

                BookChapterInfo t_chapter = null;

                string t_html = NetSiteCatchManager.ReadUrl(i_book_row["searchUrl"].ToString(), Encoding.GetEncoding(i_book_row["siteEnconding"].ToString()));
                MatchCollection t_ma = null;

                if (!string.IsNullOrEmpty(t_html))
                {
                    t_ma = Regex.Matches(t_html, i_book_row["chapterListReg"].ToString(), RegexOptions.IgnoreCase | RegexOptions.Compiled);
                    if (t_ma != null && t_ma.Count > 0)
                    {
                        SendMsg2Client(string.Format("小说：{2} 从搜索地址：{0} 得到 {1} 个章节..", i_book_row["searchUrl"].ToString(), t_ma.Count, i_book_row["bookName"]), MsgType.Total);
                    }
                    else
                    {

                        SendMsg2Client(string.Format("小说：{1} 请检查 {0} 地址..没得到章节信息", i_book_row["searchUrl"].ToString(), i_book_row["bookName"]), MsgType.Detail);

                        SendMsg2Client(string.Format("章节内容为 {0}", t_html), MsgType.Detail);

                        //重复一次
                        t_html = NetSiteCatchManager.ReadUrl(i_book_row["searchUrl"].ToString().Trim(), Encoding.GetEncoding(i_book_row["siteEnconding"].ToString()));
                        t_ma = Regex.Matches(t_html, i_book_row["chapterListReg"].ToString(), RegexOptions.IgnoreCase | RegexOptions.Compiled);
                    }
                }


                for (int index = t_chapter_index; index < t_chapter_list_source.Count; index++)
                {
                    t_chapter = t_chapter_list_source[index];

                    t_chapter.BookId = t_book_id;
                    t_chapter.SiteId = (int)Consts.Site.qidian;

                    if (t_chapter.IsVip == false)
                    {
                        t_chapter_content = m_obj.CollectChapterContent(t_chapter_list_source[index].Comfrom);
                        
                        if(string.IsNullOrEmpty(t_chapter_content)|| t_chapter_content.Length<100)
                            t_chapter_content = m_obj.CollectChapterContent(t_chapter_list_source[index].Comfrom);

                        if (string.IsNullOrEmpty(t_chapter_content) || t_chapter_content.Length < 100)
                            break;
                      

                    }
                    else
                    {
                        t_chapter_content = CollectChapterFromDBSite(t_ma, i_book_row, t_chapter);


                    }
                    if (!string.IsNullOrEmpty(t_chapter_content) && t_chapter_content.Length > 150)
                    {
                        if (t_chapter.IsVip)
                        {
                            if (!Regex.IsMatch(t_chapter_content, "[\u4E00-\u9FA5]", RegexOptions.IgnoreCase | RegexOptions.Compiled))
                            {
                                break;
                            }
                            t_vip_chapter_count++;
                        }
                        //章节入库
                        t_chapter.WordsCount = t_chapter_content.Length;
                        //章节信息保存到数据库
                        t_chapter_id = m_db_mgr.InsertBookChapter(t_chapter, t_chapter.ChapterName);

                        //章节内容保存到磁盘
                        if (t_chapter_id > 0)
                        {
                            m_file_mgr.WriteBookContent(i_book_row["bookCategoryId"].ToString(), t_book_id, t_chapter_id, t_chapter_content);
                            SendMsg2Client(string.Format("从地址：{0} 收集 {1} 章节内容,章节内容字数：{2}", t_chapter.Comfrom, t_chapter.ChapterName, t_chapter_content.Length), MsgType.Detail);
                        }
                    }
                }

                SendMsg2Client(string.Format("小说：{2} 收集到 {0} 个VIP章节,{1} 个普通章节", t_vip_chapter_count, t_chapter_count, i_book_row["bookName"]), MsgType.Total);
            }
            catch (Exception ex)
            {
                LogHelper.Error("收集小说信息失败" + ex.ToString());
            }
        }

        /// <summary>
        /// 从数据库配置的站点获取章节
        /// </summary>
        private string CollectChapterFromDBSite(MatchCollection i_ma, DataRow i_book_row, BookChapterInfo i_chapter)
        {
            string t_html = string.Empty;
            if (i_ma == null || i_ma.Count <= 0)
                return string.Empty;
            try
            {
                string t_chapter_url = GetVipChpaterUrl(i_ma, i_chapter.ChapterName, i_book_row);

                if (string.IsNullOrEmpty(t_chapter_url))
                {
                    SendMsg2Client(string.Format("检查比较章节名称的方式是否有问题,没得到章节地址,章节名称：{0}", i_chapter.ChapterName), MsgType.Detail);
                    return string.Empty;
                }

                string t_chapter_content = string.Empty;

                if (!t_chapter_url.StartsWith("http") && !t_chapter_url.StartsWith("/"))
                {
                    t_chapter_url = i_book_row["searchUrl"].ToString().Substring(0, i_book_row["searchUrl"].ToString().LastIndexOf("/") + 1) + t_chapter_url;
                }

                if (t_chapter_url.StartsWith("/"))
                {
                    t_chapter_url = i_book_row["siteDomain"].ToString() + t_chapter_url;
                }

                i_chapter.Comfrom = t_chapter_url;

                t_html = NetSiteCatchManager.ReadUrl(t_chapter_url, Encoding.GetEncoding(i_book_row["siteEnconding"].ToString()));

                if (!string.IsNullOrEmpty(t_html))
                {
                    Match t_mc_content = Regex.Match(t_html, i_book_row["chapterContentReg"].ToString().Trim(), RegexOptions.IgnoreCase | RegexOptions.Compiled);

                    if (t_mc_content != null && t_mc_content.Groups.Count > 0)
                    {
                        if (!int.TryParse(i_book_row["chapterContentIndex"].ToString(), out m_reg_index))
                            m_reg_index = 1;

                        t_chapter_content = t_mc_content.Groups[m_reg_index].Value.ToString();

                        if (i_book_row["forbidWords"] != null)
                        {
                            string t_forbid_words = i_book_row["forbidWords"].ToString();
                            string[] t_arr = t_forbid_words.Split(new char[] { '$' }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string t_words in t_arr)
                            {
                                t_chapter_content = Regex.Replace(t_chapter_content, t_words, "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                            }

                            if (string.IsNullOrEmpty(t_chapter_content))
                                return string.Empty;
                            t_chapter_content = NetSiteCatchManager.ReplaceContent(t_chapter_content);
                            t_chapter_content = string.Format("document.write('{0}');", t_chapter_content);
                            i_chapter.WordsCount = t_chapter_content.Length;
                        }
                    }


                }
                return t_chapter_content;
            }
            catch (Exception ex)
            {
                LogHelper.Error("获取其他站点章节失败" + ex.ToString());
                return string.Empty;
            }
        }

        /// <summary>
        /// 获取vip章节的地址
        /// </summary>
        /// <param name="i_mc"></param>
        /// <returns></returns>
        private string GetVipChpaterUrl(MatchCollection i_ma, string i_chapter_name, DataRow i_book_row)
        {
            string t_chapter_url = string.Empty;
            if (!int.TryParse(i_book_row["chapterNameIndex"].ToString(), out m_reg_index))
                m_reg_index = 2;
            int t_reg_chapter_url_index = 0;
            if (!int.TryParse(i_book_row["chapterUrlIndex"].ToString(), out t_reg_chapter_url_index))
                t_reg_chapter_url_index = 1;
            foreach (Match t_mc in i_ma)
            {
                if (NetSiteCatchManager.CompareChapterName(i_chapter_name, t_mc.Groups[m_reg_index].Value.ToString()))
                {
                    t_chapter_url = t_mc.Groups[t_reg_chapter_url_index].Value.ToString();
                    break;
                }
            }

            return t_chapter_url;
        }


        #region 寻找小说章节地址逻辑
        /// <summary>
        /// 开始寻找小说章节地址
        /// </summary>
        public void StartFindBookChapter()
        {
            if (SiteConfig == null)
            {
                SendMsg2Client("参数异常", MsgType.Total);
                return;
            }
            string t_book_url = string.Empty;
            for (int index = StartPageIndex; index < EndPageIndex; index++)
            {
                t_book_url = string.Format(BookUrl, index);
                FindBookChapter(t_book_url);

            }


        }

        /// <summary>
        /// 查找小说章节
        /// </summary>
        /// <param name="i_url"></param>
        private void FindBookChapter(string i_url)
        {
            try
            {
                int t_site_id = 0;
                int t_chapter_index = 0;
                int t_book_name_index = 0;
                if (!int.TryParse(SiteConfig["siteId"].ToString(), out t_site_id))
                    t_site_id = 0;
                if (!int.TryParse(SiteConfig["bookNameIndex"].ToString(), out t_book_name_index))
                    t_book_name_index = 0;
                if (!int.TryParse(SiteConfig["chapterlistUrlIndex"].ToString(), out t_chapter_index))
                    t_chapter_index = 0;
                string t_html = NetSiteCatchManager.ReadUrl(i_url, Encoding.GetEncoding(SiteConfig["siteEnconding"].ToString()));

                string t_chapter_url = string.Empty;

                if (!string.IsNullOrEmpty(t_html))
                {

                    MatchCollection t_ma = Regex.Matches(t_html, SiteConfig["bookListReg"].ToString(), RegexOptions.IgnoreCase | RegexOptions.Compiled);

                    if (t_ma != null && t_ma.Count > 0)
                    {
                        SendMsg2Client(string.Format("从小说列表地址：{0} 得到 {1} 本小说", i_url, t_ma.Count), MsgType.Total);

                        foreach (Match t_mc in t_ma)
                        {
                            t_chapter_url = t_mc.Groups[t_chapter_index].Value.ToString().Trim();
                            if (t_chapter_url.ToLower().StartsWith("http") == false)
                            {
                                Uri t_url = new Uri(i_url);
                                t_chapter_url = "http://" + t_url.Host + t_chapter_url;
                            }

                            int t_ret = m_db_mgr.AddBookSearch(t_mc.Groups[t_book_name_index].Value.ToString().Trim(), t_chapter_url, t_site_id);
                            if (t_ret > 0)
                            {
                                SendMsg2Client(string.Format("收集到书籍 {0} 章节地址", t_mc.Groups[t_book_name_index].Value.ToString()), MsgType.Detail);
                            }
                        }
                    }
                }


            }
            catch (Exception ex)
            {
                LogHelper.Error("收集手打小说网书籍url失败" + ex.ToString());

            }
        }
        #endregion
    }
}
